//
// $Id: Agent.java 9 2007-04-18 14:04:34Z z_hossain $
//
// xChess is a multiplatform graphical chess user interface
// Copyright (C) 2007  MD. Z. Hossain <z_hossain@users.sf.net>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  
// 02110-1301, USA.
//
// For more information visit http://xchess.sourceforge.net
//

package control;

import event.IMoveListener;
import event.MoveEvent;
import gui.BoardUI;
import gui.ChessClock;
import gui.IChessContext;
import gui.MoveListUI;

import java.util.ArrayList;

import model.Move;

public abstract class AbsAgent {
	
	public static final int USER_AGENT = 0;
	public static final int ENGINE_AGENT = 1;
	
	protected BoardUI boardUI;
	protected MoveListUI moveListUI;
	protected ChessClock chessClock;
	protected int agentTurn;
	
	private AbsAgent opponentAgent;
	private ArrayList<IMoveListener> listenerList = new ArrayList<IMoveListener>(2);
	private IMoveListener moveListener;
	
	public AbsAgent(IChessContext context) {
		this.boardUI = context.getBoardUI();
		this.moveListUI = context.getMoveListUI();
		this.chessClock = context.getChessClock();
	}
	
	public static AbsAgent createAgent(IChessContext context, int type) {
		switch(type) {
		case USER_AGENT:
			return new UserAgent(context);
		case ENGINE_AGENT:
			return AbsEngineAgent.createEngine(context);
		}
		return null;
	}
	
	public void addMoveListener(IMoveListener l) {
		listenerList.add(l);
	}
	
	public void removeMoveListener(IMoveListener l) {
		listenerList.remove(l);
	}
	
	protected void fireMovePerformed(MoveEvent e) {
		int count = listenerList.size();
		for(int i = 0; i < count; i++) {
			listenerList.get(i).movePerformed(e);
		}
	}
	
	public AbsAgent getOpponentAgent() {
		return opponentAgent;
	}
	
	public void setOpponentAgent(AbsAgent agent) {
		this.opponentAgent = agent;
		agent.addMoveListener(moveListener = new IMoveListener() {
			public void movePerformed(MoveEvent e) {
				AbsAgent.this.moveDeclared(e.getMove());
			}
		});
	}

	public int getTurn() {
		return agentTurn;
	}

	public void setTurn(int turn) {
		this.agentTurn = turn;
	}
	
	public void dispose() {
		opponentAgent.removeMoveListener(moveListener);
		opponentAgent = null;
	}
	
	public abstract void newGame();
	public abstract void moveDeclared(Move move);
}
